home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / mon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  45.4 KB  |  1,791 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)mon.c    3.1    93/06/12    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* If you're using precompiled headers, you don't want this either */
  6. #ifdef MICROPORT_BUG
  7. #define MKROOM_H
  8. #endif
  9.  
  10. #include "hack.h"
  11. #include "mfndpos.h"
  12. #include "edog.h"
  13. #include <ctype.h>
  14.  
  15. STATIC_DCL boolean FDECL(restrap,(struct monst *));
  16. STATIC_DCL void NDECL(dmonsfree);
  17.  
  18. #ifdef OVL1
  19. #define warnDelay 10
  20. long lastwarntime;
  21. int lastwarnlev;
  22.  
  23. const char *warnings[] = {
  24.     "white", "pink", "red", "ruby", "purple", "black"
  25. };
  26.  
  27. static void NDECL(warn_effects);
  28.  
  29. #endif /* OVL1 */
  30.  
  31. #ifdef OVLB
  32. static struct obj *FDECL(make_corpse,(struct monst *));
  33. static void FDECL(m_detach,(struct monst *));
  34.  
  35. struct monst *fdmon;    /* chain of dead monsters, need not be saved */
  36.             /* otherwise used only in priest.c */
  37.  
  38. /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
  39.  * leave corpses.  Monsters which leave "special" corpses should have
  40.  * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
  41.  * etc....
  42.  */
  43. static struct obj *
  44. make_corpse(mtmp)
  45. register struct monst *mtmp;
  46. {
  47.     register struct permonst *mdat = mtmp->data;
  48.     int num;
  49.     struct obj *obj = (struct obj *)0;
  50.     int x = mtmp->mx, y = mtmp->my;
  51.     int mndx = monsndx(mdat);
  52.  
  53.     switch(mndx) {
  54.         case PM_GRAY_DRAGON:
  55.         case PM_RED_DRAGON:
  56.         case PM_ORANGE_DRAGON:
  57.         case PM_WHITE_DRAGON:
  58.         case PM_BLACK_DRAGON:
  59.         case PM_BLUE_DRAGON:
  60.         case PM_GREEN_DRAGON:
  61.         case PM_YELLOW_DRAGON:
  62.         /* Make dragon scales.  This assumes that the order of the */
  63.         /* dragons is the same as the order of the scales.       */
  64.         if (!rn2(3)) {
  65.             obj = mksobj_at(GRAY_DRAGON_SCALES +
  66.                     monsndx(mdat)-PM_GRAY_DRAGON, x, y, FALSE);
  67.             obj->spe = 0;
  68.             obj->cursed = obj->blessed = FALSE;
  69.         }
  70.         goto default_1;
  71.  
  72.         case PM_WHITE_UNICORN:
  73.         case PM_GRAY_UNICORN:
  74.         case PM_BLACK_UNICORN:
  75.         (void) mksobj_at(UNICORN_HORN, x, y, TRUE);
  76.         goto default_1;
  77.         case PM_LONG_WORM:
  78.         (void) mksobj_at(WORM_TOOTH, x, y, TRUE);
  79.         goto default_1;
  80.         case PM_KOBOLD_MUMMY:
  81.         case PM_GNOME_MUMMY:
  82.         case PM_ORC_MUMMY:
  83.         case PM_ELF_MUMMY:
  84.         case PM_HUMAN_MUMMY:
  85.         case PM_GIANT_MUMMY:
  86.         case PM_ETTIN_MUMMY:
  87.         (void) mksobj_at(MUMMY_WRAPPING, x, y, TRUE); /* and fall through */
  88.         case PM_KOBOLD_ZOMBIE:
  89.         case PM_GNOME_ZOMBIE:
  90.         case PM_ORC_ZOMBIE:
  91.         case PM_ELF_ZOMBIE:
  92.         case PM_HUMAN_ZOMBIE:
  93.         case PM_GIANT_ZOMBIE:
  94.         case PM_ETTIN_ZOMBIE:
  95.         switch (mndx) {
  96.             case PM_KOBOLD_ZOMBIE:
  97.             case PM_KOBOLD_MUMMY:
  98.             num = PM_KOBOLD; break;
  99.             case PM_GNOME_MUMMY:
  100.             case PM_GNOME_ZOMBIE:
  101.             num = PM_GNOME; break;
  102.             case PM_ORC_MUMMY:
  103.             case PM_ORC_ZOMBIE:
  104.             num = PM_ORC; break;
  105.             case PM_ELF_MUMMY:
  106.             case PM_ELF_ZOMBIE:
  107.             num = PM_ELF; break;
  108.             case PM_HUMAN_MUMMY:
  109.             case PM_HUMAN_ZOMBIE:
  110.             num = PM_HUMAN; break;
  111.             case PM_GIANT_MUMMY:
  112.             case PM_GIANT_ZOMBIE:
  113.             num = PM_GIANT; break;
  114.             case PM_ETTIN_MUMMY:
  115.             case PM_ETTIN_ZOMBIE:
  116. #ifdef GCC_WARN
  117.             default:
  118. #endif
  119.             num = PM_ETTIN; break;
  120.         }
  121.         obj = mkcorpstat(CORPSE, &mons[num], x, y, TRUE);
  122.         obj->age -= 100;        /* this is an *OLD* corpse */
  123.         break;
  124.         case PM_IRON_GOLEM:
  125.         num = d(2,6);
  126.         while (num--)
  127.             obj = mksobj_at(IRON_CHAIN, x, y, TRUE);
  128.         mtmp->mnamelth = 0;
  129.         break;
  130.         case PM_CLAY_GOLEM:
  131.         obj = mksobj_at(ROCK, x, y, FALSE);
  132.         obj->quan = (long)(rn2(20) + 50);
  133.         obj->owt = weight(obj);
  134.         mtmp->mnamelth = 0;
  135.         break;
  136.         case PM_STONE_GOLEM:
  137.         obj = mkcorpstat(STATUE, mdat, x, y, FALSE);
  138.         break;
  139.         case PM_WOOD_GOLEM:
  140.         num = d(2,4);
  141.         while(num--) {
  142.             obj = mksobj_at(QUARTERSTAFF, x, y, TRUE);
  143.             if (obj && obj->oartifact) {    /* don't allow this */
  144.                 artifact_exists(obj, ONAME(obj), FALSE);
  145.                 Strcpy(ONAME(obj), "");  obj->onamelth = 0;
  146.             }
  147.         }
  148.         mtmp->mnamelth = 0;
  149.         break;
  150.         case PM_LEATHER_GOLEM:
  151.         num = d(2,4);
  152.         while(num--)
  153.             obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE);
  154.         mtmp->mnamelth = 0;
  155.         break;
  156.         default_1:
  157.         default:
  158.         if (mdat->geno & G_NOCORPSE)
  159.             return (struct obj *)0;
  160.         else obj = mkcorpstat(CORPSE, mdat, x, y, TRUE);
  161.         break;
  162.     }
  163.     /* All special cases should precede the G_NOCORPSE check */
  164.  
  165.     /* Note: oname() cannot be used generically for non-inventory objects
  166.      * unless you fix the link from the previous object in the chains.
  167.      * (Here we know it's the first one, so there was no link.)
  168.      */
  169.     if (mtmp->mnamelth) {
  170.         obj = oname(obj, NAME(mtmp), 0);
  171.         fobj = obj;
  172.         level.objects[x][y] = obj;
  173.     }
  174.     stackobj(fobj);
  175.     newsym(x, y);
  176.     return obj;
  177. }
  178.  
  179. #endif /* OVLB */
  180. #ifdef OVL1
  181.  
  182. static void
  183. warn_effects()
  184. {
  185.     if (warnlevel == 100) {
  186.     if(!Blind &&
  187.         (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) {
  188.         Your("%s %s!", aobjnam(uwep, "glow"),
  189.          Hallucination ? hcolor() : light_blue);
  190.         lastwarnlev = warnlevel;
  191.         lastwarntime = moves;
  192.     }
  193.     warnlevel = 0;
  194.     return;
  195.     }
  196.  
  197.     if(warnlevel >= SIZE(warnings))
  198.     warnlevel = SIZE(warnings)-1;
  199.     if(!Blind && warnlevel >= 0)
  200.     if(warnlevel > lastwarnlev || moves > lastwarntime + warnDelay) {
  201.         register const char *rr;
  202.  
  203.         lastwarntime = moves;
  204.         lastwarnlev = warnlevel;
  205.         switch((int) (Warning & (LEFT_RING | RIGHT_RING))) {
  206.         case LEFT_RING:
  207.         rr = Hallucination ? "left mood ring glows" : "left ring glows";
  208.         break;
  209.         case RIGHT_RING:
  210.         rr = Hallucination ? "right mood ring glows"
  211.             : "right ring glows";
  212.         break;
  213.         case LEFT_RING | RIGHT_RING:
  214.         rr = Hallucination ? "mood rings glow" : "rings both glow";
  215.         break;
  216.         default:
  217.         if (Hallucination)
  218.             Your("spider-sense is tingling...");
  219.         else
  220.             You("feel apprehensive as you sense a %s flash.",
  221.             warnings[warnlevel]);
  222.         return;
  223.         }
  224.         Your("%s %s!", rr, Hallucination ? hcolor() : warnings[warnlevel]);
  225.     }
  226. }
  227.  
  228. /* check mtmp and water for compatibility, 0 (survived), 1 (drowned) */
  229. int
  230. minwater(mtmp)
  231. register struct monst *mtmp;
  232. {
  233.     boolean inpool, infountain;
  234.  
  235.     inpool = is_pool(mtmp->mx,mtmp->my) &&
  236.          !is_flyer(mtmp->data) && !is_floater(mtmp->data);
  237.     infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ);
  238.  
  239.     /* Gremlin multiplying won't go on forever since the hit points
  240.      * keep going down, and when it gets to 1 hit point the clone
  241.      * function will fail.
  242.      */
  243.     if(mtmp->data->mlet == S_GREMLIN && (inpool || infountain) && rn2(3)) {
  244.     struct monst *mtmp2 = clone_mon(mtmp);
  245.  
  246.     if (mtmp2) {
  247.         mtmp2->mhpmax = (mtmp->mhpmax /= 2);
  248.         if(cansee(mtmp->mx,mtmp->my))
  249.         pline("%s multiplies.", Monnam(mtmp));
  250.         dryup(mtmp->mx,mtmp->my);
  251.     }
  252.     if (inpool) water_damage(mtmp->minvent, FALSE, FALSE);
  253.     return (0);
  254.     }
  255.     if (inpool) {
  256.     /* Most monsters drown in pools.  flooreffects() will take care of
  257.      * water damage to dead monsters' inventory, but survivors need to
  258.      * be handled here.  Swimmers are able to protect their stuff...
  259.      */
  260.     if (!is_clinger(mtmp->data)
  261.         && !is_swimmer(mtmp->data) && !amphibious(mtmp->data)) {
  262.         if (cansee(mtmp->mx,mtmp->my))
  263.         pline("%s drowns.", Monnam(mtmp));
  264.         mondead(mtmp);
  265. #ifdef MUSE
  266.         if (mtmp->mhp > 0) {
  267.         rloc(mtmp);
  268.         water_damage(mtmp->minvent, FALSE, FALSE);
  269.         return 0;
  270.         }
  271. #endif
  272.         return (1);
  273.     }
  274.     } else {
  275.     /* but eels have a difficult time outside */
  276.     if (mtmp->data->mlet == S_EEL) {
  277.         if(mtmp->mhp > 1) mtmp->mhp--;
  278.         mtmp->mflee = 1;
  279.         mtmp->mfleetim += 2;
  280.     }
  281.     }
  282.     return (0);
  283. }
  284.  
  285. void
  286. movemon()
  287. {
  288.     register struct monst *mtmp;
  289.     register boolean tametype = TRUE;
  290.  
  291.     warnlevel = 0;
  292.  
  293.     while(1) {
  294.     /* Find a monster that we have not treated yet.
  295.      * Note that mtmp or mtmp->nmon might get killed
  296.      * while mtmp moves, so we cannot just walk down the
  297.      * chain (even new monsters might get created!)
  298.      *
  299.      * Do tame monsters first.  Necessary so that when the tame
  300.      * monster attacks something, the something gets a chance to
  301.      * attack the tame monster back (which it's permitted to do
  302.      * only if it hasn't made its move yet).
  303.      */
  304.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  305.         if(mtmp->mlstmv < monstermoves &&
  306.            ((mtmp->mtame>0) == tametype)) goto next_mon;
  307.     if(tametype) {
  308.         /* checked all tame monsters, now do other ones */
  309.         tametype = FALSE;
  310.         continue;
  311.     }
  312.     /* treated all monsters */
  313.     break;
  314.  
  315.     next_mon:
  316.     mtmp->mlstmv = monstermoves;
  317.  
  318.     if(mtmp->mhp <= 0) {
  319.         impossible("Monster with zero hp?");
  320.         mtmp->mhp = mtmp->mhpmax = 1; /* repair */
  321.     }
  322.     if (minwater(mtmp)) continue;
  323.  
  324.     if(mtmp->mblinded && !--mtmp->mblinded)
  325.         mtmp->mcansee = 1;
  326.     if(mtmp->mfrozen && !--mtmp->mfrozen)
  327.         mtmp->mcanmove = 1;
  328.     if(mtmp->mfleetim && !--mtmp->mfleetim)
  329.         mtmp->mflee = 0;
  330.     if (is_hider(mtmp->data)) {
  331.         /* unwatched mimics and piercers may hide again  [MRS] */
  332.         if(restrap(mtmp))   continue;
  333.         if(mtmp->m_ap_type == M_AP_FURNITURE ||
  334.                     mtmp->m_ap_type == M_AP_OBJECT)
  335.             continue;
  336.         if(mtmp->mundetected) continue;
  337.     }
  338.     if(mtmp->mspeed != MSLOW || !(moves%2)) {
  339.         /* continue if the monster died fighting */
  340.         if (Conflict && !mtmp->iswiz && mtmp->mcansee) {
  341.         /* Note:
  342.          *  Conflict does not take effect in the first round.
  343.          *  Therefore, A monster when stepping into the area will
  344.          *  get to swing at you.
  345.          *
  346.          *  The call to fightm() must be _last_.  The monster might
  347.          *  have died if it returns 1.
  348.          */
  349.         if (couldsee(mtmp->mx,mtmp->my) &&
  350.             (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) &&
  351.                                 fightm(mtmp))
  352.              continue;    /* mon might have died */
  353.         }
  354.         if(dochugw(mtmp))
  355.         /* otherwise just move the monster */
  356.         continue;
  357.     }
  358.     if(mtmp->mspeed == MFAST && dochugw(mtmp))
  359.         continue;
  360.     }
  361.     if(warnlevel > 0)
  362.     warn_effects();
  363.  
  364.     dmonsfree(); /* remove all dead monsters */
  365. }
  366.  
  367. #endif /* OVL1 */
  368. #ifdef OVLB
  369.  
  370. void
  371. meatgold(mtmp)
  372.     register struct monst *mtmp;
  373. {
  374.     register struct obj *otmp;
  375.  
  376.     /* If a pet, eating is handled separately, in dog.c */
  377.     if (mtmp->mtame) return;
  378.  
  379.     /* Eats topmost metal object if it is there */
  380.     for (otmp = level.objects[mtmp->mx][mtmp->my];
  381.                             otmp; otmp = otmp->nexthere)
  382.         if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) &&
  383.         touch_artifact(otmp,mtmp)) {
  384.             if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  385.             pline("%s eats %s!", Monnam(mtmp),
  386.                 distant_name(otmp,doname));
  387.             else if (flags.soundok && flags.verbose)
  388.             You("hear a crunching sound.");
  389.             mtmp->meating = otmp->owt/2 + 1;
  390.             /* Heal up to the object's weight in hp */
  391.             if (mtmp->mhp < mtmp->mhpmax) {
  392.             mtmp->mhp += objects[otmp->otyp].oc_weight;
  393.             if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
  394.             }
  395.             if(otmp == uball) {
  396.             unpunish();
  397.             delobj(otmp);
  398.             } else if(otmp == uchain)
  399.             unpunish();    /* frees uchain */
  400.             else
  401.             delobj(otmp);
  402.             /* Left behind a pile? */
  403.             if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE);
  404.             newsym(mtmp->mx, mtmp->my);
  405.             break;
  406.         }
  407. }
  408.  
  409. void
  410. meatobj(mtmp)        /* for gelatinous cubes */
  411.     register struct monst *mtmp;
  412. {
  413.     register struct obj *otmp, *otmp2;
  414.  
  415.     /* If a pet, eating is handled separately, in dog.c */
  416.     if (mtmp->mtame) return;
  417.  
  418.     /* Eats organic objects, including cloth and wood, if there */
  419.     /* Engulfs others, except huge rocks and metal attached to player */
  420.     for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
  421.         otmp2 = otmp->nexthere;
  422.         if (is_organic(otmp) && !obj_resists(otmp, 5, 95) &&
  423.             touch_artifact(otmp,mtmp)) {
  424.         if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
  425.                         && !resists_ston(mtmp->data))
  426.             continue;
  427.         if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  428.             pline("%s eats %s!", Monnam(mtmp),
  429.                 distant_name(otmp, doname));
  430.         else if (flags.soundok && flags.verbose)
  431.             You("hear a slurping sound.");
  432.         /* Heal up to the object's weight in hp */
  433.         if (mtmp->mhp < mtmp->mhpmax) {
  434.             mtmp->mhp += objects[otmp->otyp].oc_weight;
  435.             if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
  436.         }
  437.         delobj(otmp);        /* munch */
  438.         } else if (otmp->oclass != ROCK_CLASS &&
  439.                     otmp != uball && otmp != uchain) {
  440.         if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
  441.             pline("%s engulfs %s.", Monnam(mtmp),
  442.                 distant_name(otmp,doname));
  443.         freeobj(otmp);
  444.         mpickobj(mtmp, otmp);    /* slurp */
  445.         }
  446.         /* Engulf & devour is instant, so don't set meating */
  447.         newsym(mtmp->mx, mtmp->my);
  448.     }
  449. }
  450.  
  451. void
  452. mpickgold(mtmp)
  453.     register struct monst *mtmp;
  454. {
  455.     register struct obj *gold;
  456.  
  457.     if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) {
  458.     mtmp->mgold += gold->quan;
  459.     delobj(gold);
  460.     if (cansee(mtmp->mx, mtmp->my) ) {
  461.         if (flags.verbose && !mtmp->isgd)
  462.         pline("%s picks up some gold.", Monnam(mtmp));
  463.         newsym(mtmp->mx, mtmp->my);
  464.     }
  465.     }
  466. }
  467.  
  468. /* Now includes giants which pick up enormous rocks.  KAA */
  469. void
  470. mpickgems(mtmp)
  471.     register struct monst *mtmp;
  472. {
  473.     register struct obj *otmp;
  474.  
  475.     for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp=otmp->nexthere)
  476.         if(throws_rocks(mtmp->data) ? otmp->otyp == BOULDER :
  477.         (otmp->oclass == GEM_CLASS &&
  478.          objects[otmp->otyp].oc_material != MINERAL))
  479.         if (touch_artifact(otmp,mtmp))
  480.         if(mtmp->data->mlet != S_UNICORN
  481.             || objects[otmp->otyp].oc_material == GEMSTONE){
  482.             if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  483.             pline("%s picks up %s.", Monnam(mtmp),
  484.                 distant_name(otmp, doname));
  485.             freeobj(otmp);
  486.             mpickobj(mtmp, otmp);
  487.             if (otmp->otyp == BOULDER)
  488.             unblock_point(otmp->ox,otmp->oy);    /* vision */
  489.             newsym(mtmp->mx, mtmp->my);
  490.             return;    /* pick only one object */
  491.         }
  492. }
  493.  
  494. #endif /* OVLB */
  495. #ifdef OVL2
  496.  
  497. void
  498. mpickstuff(mtmp, str)
  499.     register struct monst *mtmp;
  500.     register const char *str;
  501. {
  502.     register struct obj *otmp, *otmp2;
  503.  
  504. /*    prevent shopkeepers from leaving the door of their shop */
  505.     if(mtmp->isshk && inhishop(mtmp)) return;
  506.  
  507.     for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
  508.         otmp2 = otmp->nexthere;
  509. /*    Nymphs take everything.  Most monsters don't pick up corpses. */
  510.         if (
  511. #ifdef MUSE
  512.         !str ? searches_for_item(mtmp,otmp) :
  513. #endif
  514.           !!(index(str, otmp->oclass))) {
  515.         if (otmp->otyp == CORPSE && mtmp->data->mlet != S_NYMPH
  516. #ifdef MUSE
  517.     && (otmp->corpsenm != PM_COCKATRICE || !(mtmp->misc_worn_check & W_ARMG))
  518. #endif
  519.                                     )
  520.             continue;
  521.         if (!touch_artifact(otmp,mtmp)) continue;
  522.         if (!can_carry(mtmp,otmp)) continue;
  523.         if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  524.             pline("%s picks up %s.", Monnam(mtmp), doname(otmp));
  525.         freeobj(otmp);
  526.         mpickobj(mtmp, otmp);
  527. #ifdef MUSE
  528.         m_dowear(mtmp, FALSE);
  529. #endif
  530.         newsym(mtmp->mx, mtmp->my);
  531.         return;            /* pick only one object */
  532.         }
  533.     }
  534. }
  535.  
  536. #endif /* OVL2 */
  537. #ifdef OVL0
  538.  
  539. int
  540. curr_mon_load(mtmp)
  541. register struct monst *mtmp;
  542. {
  543.     register int curload = 0;
  544.     register struct obj *obj;
  545.  
  546.     for(obj = mtmp->minvent; obj; obj = obj->nobj) {
  547.         if(obj->otyp != BOULDER || !throws_rocks(mtmp->data))
  548.             curload += obj->owt;
  549.     }
  550.  
  551.     return curload;
  552. }
  553.  
  554. int
  555. max_mon_load(mtmp)
  556. register struct monst *mtmp;
  557. {
  558.     register long maxload;
  559.  
  560.     /* Base monster carrying capacity is equal to human maximum
  561.      * carrying capacity, or half human maximum if not strong.
  562.      * (for a polymorphed player, the value used would be the
  563.      * non-polymorphed carrying capacity instead of max/half max).
  564.      * This is then modified by the ratio between the monster weights
  565.      * and human weights.  Corpseless monsters are given a capacity
  566.      * proportional to their size instead of weight.
  567.      */
  568.     if (!mtmp->data->cwt)
  569.         maxload = (MAX_CARR_CAP * (long)mtmp->data->msize) / MZ_HUMAN;
  570.     else if (!strongmonst(mtmp->data)
  571.         || (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN)))
  572.         maxload = (MAX_CARR_CAP * (long)mtmp->data->cwt) / WT_HUMAN;
  573.     else    maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/
  574.  
  575.     if (!strongmonst(mtmp->data)) maxload /= 2;
  576.  
  577.     if (maxload < 1) maxload = 1;
  578.  
  579.     return (int) maxload;
  580. }
  581.  
  582. /* for restricting monsters' object-pickup */
  583. boolean
  584. can_carry(mtmp,otmp)
  585. struct monst *mtmp;
  586. struct obj *otmp;
  587. {
  588.     register int newload = otmp->owt;
  589.  
  590.     if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
  591. #ifdef MUSE
  592.             && !(mtmp->misc_worn_check & W_ARMG)
  593. #endif
  594.                         && !resists_ston(mtmp->data))
  595.         return(FALSE);
  596.     if (mtmp->isshk) return(TRUE); /* no limit */
  597.     if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE);
  598.     /* otherwise players might find themselves obligated to violate
  599.      * their alignment if the monster takes something they need
  600.      */
  601.  
  602.     /* special--boulder throwers carry unlimited amounts of boulders */
  603.     if (throws_rocks(mtmp->data) && otmp->otyp == BOULDER)
  604.         return(TRUE);
  605.  
  606.     /* nymphs deal in stolen merchandise, but not boulders or statues */
  607.     if (mtmp->data->mlet == S_NYMPH)
  608.         return((boolean)(!(otmp->oclass == ROCK_CLASS)));
  609.  
  610.     if(curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return(FALSE);
  611.  
  612.     return(TRUE);
  613. }
  614.  
  615. /* return number of acceptable neighbour positions */
  616. int
  617. mfndpos(mon, poss, info, flag)
  618.     register struct monst *mon;
  619.     coord *poss;    /* coord poss[9] */
  620.     long *info;    /* long info[9] */
  621.     long flag;
  622. {
  623.     register xchar x,y,nx,ny;
  624.     register int cnt = 0;
  625.     register uchar ntyp;
  626.     uchar nowtyp;
  627.     boolean wantpool,poolok,lavaok,nodiag;
  628.     int maxx, maxy;
  629.  
  630.     x = mon->mx;
  631.     y = mon->my;
  632.     nowtyp = levl[x][y].typ;
  633.  
  634.     nodiag = (mon->data == &mons[PM_GRID_BUG]);
  635.     wantpool = mon->data->mlet == S_EEL;
  636.     poolok = is_flyer(mon->data) || is_clinger(mon->data) ||
  637.          (is_swimmer(mon->data) && !wantpool);
  638.     lavaok = is_flyer(mon->data) || is_clinger(mon->data) ||
  639.          (mon->data == &mons[PM_FIRE_ELEMENTAL]);
  640. nexttry:    /* eels prefer the water, but if there is no water nearby,
  641.            they will crawl over land */
  642.     if(mon->mconf) {
  643.         flag |= ALLOW_ALL;
  644.         flag &= ~NOTONL;
  645.     }
  646.     if(!mon->mcansee)
  647.         flag |= ALLOW_SSM;
  648.     maxx = min(x+1,COLNO-1);
  649.     maxy = min(y+1,ROWNO-1);
  650.     for(nx = max(1,x-1); nx <= maxx; nx++)
  651.       for(ny = max(0,y-1); ny <= maxy; ny++) {
  652.         if(nx == x && ny == y) continue;
  653.         if(IS_ROCK(ntyp = levl[nx][ny].typ) &&
  654.            !((flag & ALLOW_WALL) && may_passwall(nx,ny)) &&
  655.            !((flag & ALLOW_DIG) && may_dig(nx,ny))) continue;
  656.         if(IS_DOOR(ntyp) && !amorphous(mon->data) &&
  657.            ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
  658.         (levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))
  659.            ) && !(flag & (ALLOW_WALL|ALLOW_DIG|BUSTDOOR))) continue;
  660.         if(nx != x && ny != y && (nodiag ||
  661. #ifdef REINCARNATION
  662.            ((IS_DOOR(nowtyp) &&
  663.          ((levl[x][y].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))) ||
  664.         (IS_DOOR(ntyp) &&
  665.          ((levl[nx][ny].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))))
  666. #else
  667.            ((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) ||
  668.         (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN)))
  669. #endif
  670.            ))
  671.         continue;
  672.         if((is_pool(nx,ny) == wantpool || poolok) &&
  673.            (lavaok || !is_lava(nx,ny))) {
  674.         int dispx, dispy;
  675.         boolean monseeu = (!Invis || perceives(mon->data));
  676.         boolean checkobj = OBJ_AT(nx,ny);
  677.  
  678.         /* Displacement also displaces the Elbereth/scare monster,
  679.          * as long as you are visible.
  680.          */
  681.         if(Displaced && monseeu && (mon->mux==nx) && (mon->muy==ny)) {
  682.             dispx = u.ux;
  683.             dispy = u.uy;
  684.         } else {
  685.             dispx = nx;
  686.             dispy = ny;
  687.         }
  688.  
  689.         info[cnt] = 0;
  690.         if(((checkobj || Displaced) &&
  691.             sobj_at(SCR_SCARE_MONSTER, dispx, dispy))
  692. #ifdef ELBERETH
  693.                || sengr_at("Elbereth", dispx, dispy)
  694. #endif
  695.                ) {
  696.             if(!(flag & ALLOW_SSM)) continue;
  697.             info[cnt] |= ALLOW_SSM;
  698.         }
  699.         if((nx == u.ux && ny == u.uy) ||
  700.            (nx == mon->mux && ny == mon->muy)) {
  701.             if (nx == u.ux && ny == u.uy) {
  702.                 /* If it's right next to you, it found you,
  703.                  * displaced or no.  We must set mux and muy
  704.                  * right now, so when we return we can tell
  705.                  * that the ALLOW_U means to attack _you_ and
  706.                  * not the image.
  707.                  */
  708.                 mon->mux = u.ux;
  709.                 mon->muy = u.uy;
  710.             }
  711.             if(!(flag & ALLOW_U)) continue;
  712.             info[cnt] |= ALLOW_U;
  713.         } else {
  714.             if(MON_AT(nx, ny)) {
  715.                 if(!(flag & ALLOW_M)) continue;
  716.                 info[cnt] |= ALLOW_M;
  717.                 if((m_at(nx,ny))->mtame) {
  718.                     if(!(flag & ALLOW_TM)) continue;
  719.                     info[cnt] |= ALLOW_TM;
  720.                 }
  721.             }
  722.             /* Note: ALLOW_SANCT only prevents movement, not */
  723.             /* attack, into a temple. */
  724.             if(level.flags.has_temple &&
  725.                *in_rooms(nx, ny, TEMPLE) &&
  726.                !*in_rooms(x, y, TEMPLE) &&
  727.                in_your_sanctuary(nx, ny)){
  728.                 if(!(flag & ALLOW_SANCT)) continue;
  729.                 info[cnt] |= ALLOW_SANCT;
  730.             }
  731.         }
  732.         if(checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
  733.             if(flag & NOGARLIC) continue;
  734.             info[cnt] |= NOGARLIC;
  735.         }
  736.         if(checkobj && sobj_at(BOULDER, nx, ny)) {
  737.             if(!(flag & ALLOW_ROCK)) continue;
  738.             info[cnt] |= ALLOW_ROCK;
  739.         }
  740.         if (monseeu && onlineu(nx,ny)) {
  741.             if(flag & NOTONL) continue;
  742.             info[cnt] |= NOTONL;
  743.         }
  744.         /* we cannot avoid traps of an unknown kind */
  745.         { register struct trap *ttmp = t_at(nx, ny);
  746.           register long tt;
  747.             if(ttmp) {
  748.                 if(ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0)  {
  749. impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp);
  750.                     continue;
  751.                 }
  752.                 tt = 1L << ttmp->ttyp;
  753.                 if(mon->mtrapseen & tt) {
  754.  
  755.                     if(!(flag & tt)) continue;
  756.                     info[cnt] |= tt;
  757.                 }
  758.             }
  759.         }
  760.         poss[cnt].x = nx;
  761.         poss[cnt].y = ny;
  762.         cnt++;
  763.         }
  764.     }
  765.     if(!cnt && wantpool && !is_pool(x,y)) {
  766.         wantpool = FALSE;
  767.         goto nexttry;
  768.     }
  769.     return(cnt);
  770. }
  771.  
  772. #endif /* OVL0 */
  773. #ifdef OVL1
  774.  
  775. boolean
  776. monnear(mon, x, y)
  777. register struct monst *mon;
  778. register int x,y;
  779. /* Is the square close enough for the monster to move or attack into? */
  780. {
  781.     register int distance = dist2(mon->mx, mon->my, x, y);
  782.     if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0;
  783.     return((boolean)(distance < 3));
  784. }
  785.  
  786. #endif /* OVL1 */
  787. #ifdef OVL2
  788.  
  789. STATIC_OVL void
  790. dmonsfree()
  791. {
  792. register struct monst *mtmp;
  793.     while ((mtmp = fdmon) != 0) {
  794.         fdmon = mtmp->nmon;
  795.         dealloc_monst(mtmp);
  796.     }
  797. }
  798.  
  799. #endif /* OVL2 */
  800. #ifdef OVLB
  801. /* we do not free monsters immediately, in order to have their name
  802.    available shortly after their demise */
  803. void
  804. monfree(mtmp)
  805. register struct monst *mtmp;
  806. {
  807.     mtmp->nmon = fdmon;
  808.     fdmon = mtmp;
  809. }
  810.  
  811. /* called when monster is moved to larger structure */
  812. void
  813. replmon(mtmp, mtmp2)
  814. register struct monst *mtmp, *mtmp2;
  815. {
  816.     relmon(mtmp);
  817.     monfree(mtmp);
  818.     place_monster(mtmp2, mtmp2->mx, mtmp2->my);
  819.     if (mtmp2->wormno)        /* update level.monsters[wseg->wx][wseg->wy] */
  820.     place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */
  821.     mtmp2->nmon = fmon;
  822.     fmon = mtmp2;
  823.     if (u.ustuck == mtmp) u.ustuck = mtmp2;
  824.     if (mtmp2->isshk) replshk(mtmp,mtmp2);
  825. }
  826.  
  827. /* release mon from display and monster list */
  828. void
  829. relmon(mon)
  830. register struct monst *mon;
  831. {
  832.     register struct monst *mtmp;
  833.  
  834.     if (fmon == (struct monst *)0)  panic ("relmon: no fmon available.");
  835.  
  836.     remove_monster(mon->mx, mon->my);
  837.  
  838.     if(mon == fmon) fmon = fmon->nmon;
  839.     else {
  840.         for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ;
  841.         if(mtmp)    mtmp->nmon = mon->nmon;
  842.         else        panic("relmon: mon not in list.");
  843.     }
  844. }
  845.  
  846. /* remove effects of mtmp from other data structures */
  847. static void
  848. m_detach(mtmp)
  849. register struct monst *mtmp;
  850. {
  851. #ifdef WALKIES
  852.     if(mtmp->mleashed) m_unleash(mtmp);
  853. #endif
  854.         /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
  855.     mtmp->mtrapped = 0;
  856.     mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
  857.     relobj(mtmp, 0, FALSE);
  858.     relmon(mtmp);
  859.     newsym(mtmp->mx,mtmp->my);
  860.     unstuck(mtmp);
  861.     fill_pit(mtmp->mx, mtmp->my);
  862.  
  863.     if(mtmp->isshk) shkgone(mtmp);
  864.     if(mtmp->wormno) wormgone(mtmp);
  865. }
  866.  
  867. #ifdef MUSE
  868. static void FDECL(lifesaved_monster, (struct monst *));
  869.  
  870. static void
  871. lifesaved_monster(mtmp)
  872. struct monst *mtmp;
  873. {
  874.     struct obj *lifesave;
  875.  
  876.     if ((lifesave = which_armor(mtmp, W_AMUL))
  877.             && lifesave->otyp == AMULET_OF_LIFE_SAVING) {
  878.         pline("But wait...");
  879.         if (canseemon(mtmp)) {
  880.             pline("%s's medallion begins to glow!",
  881.                 Monnam(mtmp));
  882.             makeknown(AMULET_OF_LIFE_SAVING);
  883.             pline("%s looks much better!", Monnam(mtmp));
  884.             pline("The medallion crumbles to dust!");
  885.         } else
  886.             pline("Maybe not...");
  887.         m_useup(mtmp, lifesave);
  888.         if (mtmp->mhpmax <= 0) mtmp->mhpmax = 10;
  889.         mtmp->mhp = mtmp->mhpmax;
  890.         mtmp->mcanmove = 1;
  891.         mtmp->mfrozen = 0;
  892.         if (mtmp->mtame && !mtmp->isminion) {
  893.             struct edog *edog = EDOG(mtmp);
  894.             if (edog->hungrytime < moves+500)
  895.                 edog->hungrytime = moves+500;
  896.         }
  897.         if (mtmp->data->geno & G_GENOD)
  898.             pline("Unfortunately %s is still genocided...",
  899.                 mon_nam(mtmp));
  900.         else
  901.             return;
  902.     }
  903.     mtmp->mhp = 0;
  904. }
  905. #endif
  906.  
  907. void
  908. mondead(mtmp)
  909. register struct monst *mtmp;
  910. {
  911.     int tmp, nk;
  912.  
  913.     if(mtmp->isgd) {
  914.         /* if we're going to abort the death, it *must* be before
  915.          * the m_detach or there will be relmon problems later */
  916.         if(!grddead(mtmp)) return;
  917.     }
  918. #ifdef MUSE
  919.     lifesaved_monster(mtmp);
  920.     if (mtmp->mhp > 0) return;
  921. #endif
  922.  
  923.     /* restore chameleon, lycanthropes to true form at death */
  924.     if(mtmp->cham) mtmp->data = &mons[PM_CHAMELEON];
  925.     if(mtmp->data == &mons[PM_WEREJACKAL])
  926.         mtmp->data = &mons[PM_HUMAN_WEREJACKAL];
  927.     if(mtmp->data == &mons[PM_WEREWOLF])
  928.         mtmp->data = &mons[PM_HUMAN_WEREWOLF];
  929.     if(mtmp->data == &mons[PM_WERERAT])
  930.         mtmp->data = &mons[PM_HUMAN_WERERAT];
  931.  
  932.     /* if MAXMONNO monsters of a given type have died, and it
  933.      * can be done, extinguish that monster.
  934.      *
  935.      * u.nr_killed does double duty as total number of dead monsters
  936.      * and as experience factor for the player killing more monsters.
  937.      * this means that a dragon dying by other means reduces the
  938.      * experience the player gets for killing a dragon directly; this
  939.      * is probably not too bad, since the player likely finagled the
  940.      * first dead dragon via ring of conflict or pets, and extinguishing
  941.      * based on only player kills probably opens more avenues of abuse
  942.      * for rings of conflict and such.
  943.      */
  944.     tmp = monsndx(mtmp->data);
  945.     u.nr_killed[tmp]++;
  946.     nk = u.nr_killed[tmp];
  947.     if(nk > (tmp == PM_NAZGUL ? 9 : tmp == PM_ERINYES ? 3 : MAXMONNO) &&
  948.                 !(mons[tmp].geno & (G_NOGEN | G_EXTINCT))) {
  949. #ifdef DEBUG
  950.         pline("Automatically extinguished %s.", makeplural(mons[tmp].mname));
  951. #endif
  952.         mons[tmp].geno |= G_EXTINCT;
  953.     }
  954. #ifdef MAIL
  955.     /* if the mail daemon dies, no more mail delivery.  -3. */
  956.     else if(tmp==PM_MAIL_DAEMON) mons[tmp].geno |= G_GENOD;
  957. #endif
  958.  
  959. #ifdef KOPS
  960.     if(mtmp->data->mlet == S_KOP && allow_kops) {
  961.         /* Dead Kops may come back. */
  962.         switch(rnd(5)) {
  963.         case 1:         /* returns near the stairs */
  964.             (void) makemon(mtmp->data,xdnstair,ydnstair);
  965.             break;
  966.         case 2:         /* randomly */
  967.             (void) makemon(mtmp->data,0,0);
  968.             break;
  969.         default:
  970.             break;
  971.         }
  972.     }
  973. #endif
  974.     if(mtmp->iswiz) wizdead(mtmp);
  975. #ifdef MULDGN
  976.     if(mtmp->data->msound == MS_NEMESIS) nemdead();
  977. #endif
  978.     m_detach(mtmp);
  979.     monfree(mtmp);
  980. }
  981.  
  982. /* drop (perhaps) a cadaver and remove monster */
  983. void
  984. mondied(mdef)
  985. register struct monst *mdef;
  986. {
  987.     mondead(mdef);
  988. #ifdef MUSE
  989.     if(mdef->mhp > 0) return; /* lifesaved */
  990. #endif
  991.     if(rn2(3)
  992. #ifdef REINCARNATION
  993.        && !Is_rogue_level(&u.uz)
  994. #endif
  995.        && !(level.flags.graveyard && is_undead(mdef->data) && rn2(3)))
  996.         (void) make_corpse(mdef);
  997. }
  998.  
  999. /* monster disappears, not dies */
  1000. void
  1001. mongone(mdef)
  1002. register struct monst *mdef;
  1003. {
  1004.     register struct obj *otmp, *otmp2;
  1005.  
  1006.     /* release monster's inventory */
  1007.     for (otmp = mdef->minvent; otmp; otmp = otmp2) {
  1008.         otmp2 = otmp->nobj;
  1009.         obfree(otmp, (struct obj *)0);
  1010.     }
  1011.     mdef->minvent = 0;
  1012.     mdef->mgold = 0;
  1013.     m_detach(mdef);
  1014.     monfree(mdef);
  1015. }
  1016.  
  1017. /* drop a statue or rock and remove monster */
  1018. void
  1019. monstone(mdef)
  1020. register struct monst *mdef;
  1021. {
  1022.     struct obj *otmp, *obj, *nxt, *contents;
  1023.     xchar x = mdef->mx, y = mdef->my;
  1024.  
  1025. #ifdef MUSE
  1026.     /* we have to make the statue before calling mondead, to be able to
  1027.      * put inventory in it, and we have to check for lifesaving before
  1028.      * making the statue....
  1029.      */
  1030.     lifesaved_monster(mdef);
  1031.     if (mdef->mhp > 0) return;
  1032. #endif
  1033.     mdef->mtrapped = 0;    /* (see m_detach) */
  1034.  
  1035.     if((int)mdef->data->msize > MZ_TINY ||
  1036.        !rn2(2 + ((mdef->data->geno & G_FREQ) > 2))) {
  1037.         otmp = mk_named_object(STATUE, mdef->data, x, y,
  1038.                     NAME(mdef), (int)mdef->mnamelth);
  1039.         /* some objects may end up outside the statue */
  1040.         contents = 0;
  1041.         for (obj = mdef->minvent; obj; obj = nxt) {
  1042.             nxt = obj->nobj;
  1043.             obj->owornmask = 0L;
  1044.             if (obj->otyp == BOULDER ||
  1045. #if 0                /* monsters don't carry statues */
  1046.      (obj->otyp == STATUE && mons[obj->corpsenm].msize >= mdef->data->msize) ||
  1047. #endif
  1048.                 obj_resists(obj, 0, 0)) {
  1049.             if (flooreffects(obj, x, y, "fall")) continue;
  1050.             place_object(obj, x, y);
  1051.             obj->nobj = fobj;
  1052.             fobj = obj;
  1053.             } else {
  1054.             obj->nobj = contents;
  1055.             contents = obj;
  1056.             }
  1057.         }
  1058.         otmp->cobj = contents;
  1059.         mdef->minvent = 0;
  1060.         if (mdef->mgold) {
  1061.             struct obj *au;
  1062.             au = mksobj(GOLD_PIECE, FALSE, FALSE);
  1063.             au->quan = mdef->mgold;
  1064.             au->owt = weight(au);
  1065.             mdef->mgold = 0;
  1066.             au->nobj = otmp->cobj;
  1067.             otmp->cobj = au;
  1068.         }
  1069.         otmp->owt = weight(otmp);
  1070.     } else
  1071.         otmp = mksobj_at(ROCK, x, y, TRUE);
  1072.  
  1073.     stackobj(otmp);
  1074.     if (cansee(x, y)) newsym(x,y);
  1075.     mondead(mdef);
  1076. }
  1077.  
  1078. /* another monster has killed the monster mdef */
  1079. void
  1080. monkilled(mdef, fltxt, how)
  1081. register struct monst *mdef;
  1082. const char *fltxt;
  1083. int how;
  1084. {
  1085.     if (cansee(mdef->mx, mdef->my) && fltxt)
  1086.         pline("%s is %s%s%s!", Monnam(mdef),
  1087.             (is_demon(mdef->data) || is_undead(mdef->data)) ?
  1088.              "destroyed" : "killed",
  1089.             *fltxt ? " by the " : "",
  1090.             fltxt
  1091.          );
  1092.     else if(mdef->mtame)
  1093.         You("have a sad feeling for a moment, then it passes.");
  1094.  
  1095.     /* no corpses if digested */
  1096.     if(how == AD_DGST)
  1097.         mondead(mdef);
  1098.     else
  1099.         mondied(mdef);
  1100. }
  1101.  
  1102. void
  1103. unstuck(mtmp)
  1104. register struct monst *mtmp;
  1105. {
  1106.     if(u.ustuck == mtmp) {
  1107.         if(u.uswallow){
  1108.             u.ux = mtmp->mx;
  1109.             u.uy = mtmp->my;
  1110.             u.uswallow = 0;
  1111.             u.uswldtim = 0;
  1112.             if (Punished) placebc();
  1113.             vision_full_recalc = 1;
  1114.             docrt();
  1115.         }
  1116.         u.ustuck = 0;
  1117.     }
  1118. }
  1119.  
  1120. void
  1121. killed(mtmp)
  1122. register struct monst *mtmp;
  1123. {
  1124.     xkilled(mtmp, 1);
  1125. }
  1126.  
  1127. /* the player has killed the monster mtmp */
  1128. void
  1129. xkilled(mtmp, dest)
  1130.     register struct monst *mtmp;
  1131. /*
  1132.  * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse
  1133.  * either; dest=3, message but no corpse
  1134.  */
  1135.     int    dest;
  1136. {
  1137.     register int tmp, x = mtmp->mx, y = mtmp->my;
  1138.     register struct permonst *mdat;
  1139.     register struct obj *otmp;
  1140.     register struct trap *t;
  1141.     boolean chance, redisp = FALSE;
  1142.     boolean wasinside = u.uswallow && (u.ustuck == mtmp);
  1143.  
  1144.     if (dest & 1) {
  1145.         if(!wasinside && !canseemon(mtmp) && !sensemon(mtmp))
  1146.         You("destroy it!");
  1147.         else {
  1148.         You("destroy %s!",
  1149.             mtmp->mtame ? x_monnam(mtmp, 0, "poor", 0)
  1150.             : mon_nam(mtmp));
  1151.         }
  1152.     }
  1153.  
  1154.     if (mtmp->mtrapped &&
  1155.         ((t = t_at(x, y)) && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) &&
  1156.         sobj_at(BOULDER, x, y))
  1157.         dest ^= 2; /*
  1158.                 * Prevent corpses/treasure being created "on top"
  1159.                 * of the boulder that is about to fall in. This is
  1160.                 * out of order, but cannot be helped unless this
  1161.                 * whole routine is rearranged.
  1162.                 */
  1163.  
  1164.     /* dispose of monster and make cadaver */
  1165.     if(stoned) monstone(mtmp);
  1166.     else mondead(mtmp);
  1167.  
  1168. #ifdef MUSE
  1169.     if (mtmp->mhp > 0) return; /* monster lifesaved */
  1170. #endif
  1171.  
  1172.     mdat = mtmp->data; /* note: mondead can change mtmp->data */
  1173.  
  1174.     if (stoned) {
  1175.         stoned = FALSE;
  1176.         goto cleanup;
  1177.     }
  1178.  
  1179.     if((dest & 2)
  1180. #ifdef REINCARNATION
  1181.          || Is_rogue_level(&u.uz)
  1182. #endif
  1183.        || (level.flags.graveyard && is_undead(mdat) && rn2(3)))
  1184.         goto cleanup;
  1185.  
  1186. #ifdef MAIL
  1187.     if(mdat == &mons[PM_MAIL_DAEMON]) {
  1188.         (void) mksobj_at(SCR_MAIL, x, y, FALSE);
  1189.         stackobj(fobj);
  1190.         redisp = TRUE;
  1191.     }
  1192. #endif
  1193.     if(!accessible(x, y)) {
  1194.         /* might be mimic in wall or dead eel or in a pool or lava */
  1195.         redisp = TRUE;
  1196.         if(wasinside) spoteffects();
  1197.     } else if(x != u.ux || y != u.uy) {
  1198.         /* might be here after swallowed */
  1199.         if (!rn2(6) && !(mdat->geno & G_NOCORPSE)
  1200. #ifdef KOPS
  1201.                     && mdat->mlet != S_KOP
  1202. #endif
  1203.                             ) {
  1204.             int typ;
  1205.  
  1206.             otmp = mkobj_at(RANDOM_CLASS, x, y, TRUE);
  1207.             /* Don't create large objects from small monsters */
  1208.             typ = otmp->otyp;
  1209.             if (mdat->msize < MZ_HUMAN && typ != FOOD_RATION
  1210. #ifdef WALKIES
  1211.                 && typ != LEASH
  1212. #endif
  1213.                 && typ != FIGURINE
  1214.                 && (otmp->owt > 3 ||
  1215.                 (typ >= SPEAR && typ <= LANCE) ||
  1216.                 (typ >= SCIMITAR && typ <= KATANA) ||
  1217.                 (typ == MORNING_STAR || typ == QUARTERSTAFF) ||
  1218.                 (typ >= BARDICHE && typ <= VOULGE) ||
  1219.                 (typ >= PLATE_MAIL &&
  1220.                         typ <= YELLOW_DRAGON_SCALE_MAIL) ||
  1221.                 (typ == LARGE_SHIELD))) {
  1222.                 delobj(otmp);
  1223.             } else redisp = TRUE;
  1224.         }
  1225.         /* Whether or not it always makes a corpse is, in theory,
  1226.          * different from whether or not the corpse is "special";
  1227.          * if we want both, we have to specify it explicitly.
  1228.          */
  1229.         if (bigmonst(mdat) || mdat == &mons[PM_LIZARD]
  1230.                || is_golem(mdat)
  1231.                || is_mplayer(mdat)
  1232.                || is_rider(mdat))
  1233.             chance = 1;
  1234.         else chance = !rn2((int)
  1235.             (2 + ((mdat->geno & G_FREQ)<2) + verysmall(mdat)));
  1236.         if (chance)
  1237.             (void) make_corpse(mtmp);
  1238.     }
  1239.     if(redisp) newsym(x,y);
  1240. cleanup:
  1241.     /* punish bad behaviour */
  1242.     if(is_human(mdat) && (!always_hostile(mdat) && mtmp->malign <= 0) &&
  1243.        (monsndx(mdat) < PM_ARCHEOLOGIST || monsndx(mdat) > PM_WIZARD) &&
  1244.        u.ualign.type != A_CHAOTIC) {
  1245.         HTelepat &= ~INTRINSIC;
  1246.         change_luck(-2);
  1247.         if (Blind && !Telepat)
  1248.             see_monsters(); /* Can't sense monsters any more. */
  1249.     }
  1250.     if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)    change_luck(-1);
  1251.     if (mdat->mlet == S_UNICORN &&
  1252.                 sgn(u.ualign.type) == sgn(mdat->maligntyp))
  1253.         change_luck(-5);
  1254.  
  1255.     /* give experience points */
  1256.     tmp = experience(mtmp, u.nr_killed[monsndx(mdat)] + 1);
  1257.     more_experienced(tmp, 0);
  1258.     newexplevel();        /* will decide if you go up */
  1259.  
  1260.     /* adjust alignment points */
  1261. #ifdef MULDGN
  1262.     if(mdat->msound == MS_LEADER)        /* REAL BAD! */
  1263.         adjalign(-(u.ualign.record+(int)ALIGNLIM/2));
  1264.     else if(mdat->msound == MS_NEMESIS)    /* Real good! */
  1265.         adjalign((int)(ALIGNLIM/4));
  1266.     else if(mdat->msound == MS_GUARDIAN)    /* Bad */
  1267.         adjalign(-(int)(ALIGNLIM/8));
  1268.     else
  1269. #endif
  1270.         if (mtmp->ispriest) {
  1271.         adjalign((p_coaligned(mtmp)) ? -2 : 2);
  1272.         if(mdat->maligntyp == A_NONE)
  1273.             adjalign((int)(ALIGNLIM / 4));        /* BIG bonus */
  1274.     } else if(mtmp->mtame)
  1275.         adjalign(-15);    /* bad!! */
  1276.     else if (mtmp->mpeaceful)
  1277.         adjalign(-5);
  1278.  
  1279.     /* malign was already adjusted for u.ualign.type and randomization */
  1280.     adjalign(mtmp->malign);
  1281. }
  1282.  
  1283. /* changes the monster into a stone monster of the same type */
  1284. /* this should only be called when poly_when_stoned() is true */
  1285. void
  1286. mon_to_stone(mtmp)
  1287.     register struct monst *mtmp;
  1288. {
  1289.     if(mtmp->data->mlet == S_GOLEM) {
  1290.     /* it's a golem, and not a stone golem */
  1291.     if(canseemon(mtmp))
  1292.         pline("%s solidifies...", Monnam(mtmp));
  1293.     (void) newcham(mtmp, &mons[PM_STONE_GOLEM]);
  1294.     if(canseemon(mtmp))
  1295.         pline("Now it's %s", a_monnam(mtmp));
  1296.     } else
  1297.     impossible("Can't polystone %s", a_monnam(mtmp));
  1298. }
  1299.  
  1300. void
  1301. mnexto(mtmp)    /* Make monster mtmp next to you (if possible) */
  1302.     struct monst *mtmp;
  1303. {
  1304.     coord mm;
  1305.  
  1306.     if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return;
  1307.  
  1308.     rloc_to(mtmp, mm.x, mm.y);
  1309. }
  1310.  
  1311. /* mnearto()
  1312.  * Put monster near (or at) location if possible.
  1313.  * Returns:
  1314.  *    1 - if a monster was moved from x, y to put mtmp at x, y.
  1315.  *    0 - in most cases.
  1316.  */
  1317. boolean
  1318. mnearto(mtmp,x,y,move_other)
  1319. register struct monst *mtmp;
  1320. xchar x, y;
  1321. boolean move_other;    /* make sure mtmp gets to x, y! so move m_at(x, y) */
  1322. {
  1323.     struct monst *othermon = (struct monst *)0;
  1324.     xchar newx, newy;
  1325.     coord mm;
  1326.  
  1327.     if ((mtmp->mx == x) && (mtmp->my == y)) return(FALSE);
  1328.  
  1329.     if (move_other && (othermon = m_at(x, y))) {
  1330.         if (othermon->wormno)
  1331.             remove_worm(othermon);
  1332.         else
  1333.             remove_monster(x, y);
  1334.     }
  1335.  
  1336.     newx = x;
  1337.     newy = y;
  1338.  
  1339.     if (!goodpos(newx, newy, mtmp, mtmp->data)) {
  1340.         /* actually we have real problems if enexto ever fails.
  1341.          * migrating_mons that need to be placed will cause
  1342.          * no end of trouble.
  1343.          */
  1344.         if (!enexto(&mm, newx, newy, mtmp->data)) return(FALSE);
  1345.         newx = mm.x; newy = mm.y;
  1346.     }
  1347.  
  1348.     rloc_to(mtmp, newx, newy);
  1349.  
  1350.     if (move_other && othermon) {
  1351.         othermon->mx = othermon->my = 0;
  1352.         (void) mnearto(othermon, x, y, FALSE);
  1353.         if ((othermon->mx != x) || (othermon->my != y))
  1354.         return(TRUE);
  1355.     }
  1356.  
  1357.     return(FALSE);
  1358. }
  1359.  
  1360.  
  1361. static const char *poiseff[] = {
  1362.  
  1363.     " feel very weak", "r brain is on fire",
  1364.     "r judgement is impaired", "r muscles won't obey you",
  1365.     " feel very sick", " break out in hives"
  1366. };
  1367.  
  1368. void
  1369. poisontell(typ)
  1370.  
  1371.     int    typ;
  1372. {
  1373.     pline("You%s.", poiseff[typ]);
  1374. }
  1375.  
  1376. void
  1377. poisoned(string, typ, pname, fatal)
  1378. register const char *string, *pname;
  1379. register int  typ, fatal;
  1380. {
  1381.     register int i, plural;
  1382.     boolean thrown_weapon = !strncmp(string, "poison", 6);
  1383.         /* admittedly a kludge... */
  1384.  
  1385.     if(strcmp(string, "blast") && !thrown_weapon) {
  1386.         /* 'blast' has already given a 'poison gas' message */
  1387.         /* so have "poison arrow", "poison dart", etc... */
  1388.         plural = (string[strlen(string) - 1] == 's')? 1 : 0;
  1389.         /* avoid "The" Orcus's sting was poisoned... */
  1390.         pline("%s%s %s poisoned!", isupper(*string) ? "" : "The ",
  1391.             string, plural ? "were" : "was");
  1392.     }
  1393.  
  1394.     if(Poison_resistance) {
  1395.         if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy);
  1396.         pline("The poison doesn't seem to affect you.");
  1397.         return;
  1398.     }
  1399.     i = rn2(fatal + 20*thrown_weapon);
  1400.     if(i == 0 && typ != A_CHA) {
  1401.         u.uhp = -1;
  1402.         pline("The poison was deadly...");
  1403.     } else if(i <= 5) {
  1404.         pline("You%s!", poiseff[typ]);
  1405.         (void) adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), TRUE);
  1406.     } else {
  1407.         i = thrown_weapon ? rnd(6) : rn1(10,6);
  1408.         if(Half_physical_damage) i = (i+1) / 2;
  1409.         losehp(i, pname, KILLED_BY_AN);
  1410.     }
  1411.     if(u.uhp < 1) {
  1412.         killer_format = KILLED_BY_AN;
  1413.         killer = pname;
  1414.         done(POISONING);
  1415.     }
  1416. }
  1417.  
  1418. /* monster responds to player action; not the same as a passive attack */
  1419. /* assumes reason for response has been tested, and response _must_ be made */
  1420. void
  1421. m_respond(mtmp)
  1422. register struct monst *mtmp;
  1423. {
  1424.     if(mtmp->data->msound == MS_SHRIEK) {
  1425.     if(flags.soundok)
  1426.         pline("%s shrieks.", Monnam(mtmp));
  1427.     if (!rn2(10)) {
  1428.         if (!rn2(13))
  1429.         (void) makemon(&mons[PM_PURPLE_WORM], 0, 0);
  1430.         else
  1431.         (void) makemon((struct permonst *)0, 0, 0);
  1432.  
  1433.     }
  1434.     aggravate();
  1435.     }
  1436.     if(mtmp->data == &mons[PM_MEDUSA] && !mtmp->mcan) {
  1437.     register int i;
  1438.     for(i = 0; i < NATTK; i++)
  1439.          if(mtmp->data->mattk[i].aatyp == AT_GAZE) {
  1440.          (void) gazemu(mtmp, &mtmp->data->mattk[i]);
  1441.          break;
  1442.          }
  1443.     }
  1444. }
  1445.  
  1446. #endif /* OVLB */
  1447. #ifdef OVL2
  1448.  
  1449. void
  1450. setmangry(mtmp)
  1451. register struct monst *mtmp;
  1452. {
  1453.     mtmp->data->mflags3 &= ~M3_WAITMASK;
  1454.     if(!mtmp->mpeaceful) return;
  1455.     if(mtmp->mtame) return;
  1456.     mtmp->mpeaceful = 0;
  1457.     if(mtmp->ispriest) {
  1458.         if(p_coaligned(mtmp)) adjalign(-5); /* very bad */
  1459.         else adjalign(2);
  1460.     } else
  1461.         adjalign(-1);        /* attacking peaceful monsters is bad */
  1462.     if(humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd)
  1463.         pline("%s gets angry!", Monnam(mtmp));
  1464. #ifdef SOUNDS
  1465.     else if (flags.verbose && flags.soundok) growl(mtmp);
  1466. #endif
  1467. }
  1468.  
  1469. void
  1470. wakeup(mtmp)
  1471. register struct monst *mtmp;
  1472. {
  1473.     mtmp->msleep = 0;
  1474.     mtmp->meating = 0;    /* assume there's no salvagable food left */
  1475.     setmangry(mtmp);
  1476.     if(mtmp->m_ap_type) seemimic(mtmp);
  1477. }
  1478.  
  1479. /* Wake up nearby monsters. */
  1480. void
  1481. wake_nearby()
  1482. {
  1483.     register struct monst *mtmp;
  1484.  
  1485.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1486.         if (distu(mtmp->mx,mtmp->my) < u.ulevel*20) {
  1487.         if(mtmp->msleep)  mtmp->msleep = 0;
  1488.         if(mtmp->mtame)   EDOG(mtmp)->whistletime = moves;
  1489.         }
  1490.     }
  1491. }
  1492.  
  1493. /* NOTE: we must check for mimicry before calling this routine */
  1494. void
  1495. seemimic(mtmp)
  1496. register struct monst *mtmp;
  1497. {
  1498.     /*
  1499.      *  Discovered mimics don't block light.
  1500.      */
  1501.     if ((mtmp->m_ap_type == M_AP_FURNITURE &&
  1502.         (mtmp->mappearance==S_hcdoor || mtmp->mappearance==S_vcdoor))||
  1503.         (mtmp->m_ap_type == M_AP_OBJECT && mtmp->mappearance == BOULDER))
  1504.         unblock_point(mtmp->mx,mtmp->my);
  1505.  
  1506.     mtmp->m_ap_type = M_AP_NOTHING;
  1507.     mtmp->mappearance = 0;
  1508.     newsym(mtmp->mx,mtmp->my);
  1509. }
  1510.  
  1511. /* force all chameleons to become normal */
  1512. void
  1513. rescham()
  1514. {
  1515.     register struct monst *mtmp;
  1516.  
  1517.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1518.         if(mtmp->cham) {
  1519.             mtmp->cham = 0;
  1520.             (void) newcham(mtmp, &mons[PM_CHAMELEON]);
  1521.         }
  1522.         if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
  1523.             new_were(mtmp);
  1524.         if(mtmp->m_ap_type && cansee(mtmp->mx, mtmp->my)) {
  1525.             seemimic(mtmp);
  1526.             /* we pretend that the mimic doesn't */
  1527.             /* know that it has been unmasked.   */
  1528.             mtmp->msleep = 1;
  1529.         }
  1530.     }
  1531. }
  1532.  
  1533. /* Let the chameleons change again -dgk */
  1534. void
  1535. restartcham()
  1536. {
  1537.     register struct monst *mtmp;
  1538.  
  1539.     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1540.         if (mtmp->data == &mons[PM_CHAMELEON])
  1541.             mtmp->cham = 1;
  1542.         if(mtmp->data->mlet == S_MIMIC && mtmp->msleep &&
  1543.                 cansee(mtmp->mx, mtmp->my)) {
  1544.             set_mimic_sym(mtmp);
  1545.             newsym(mtmp->mx,mtmp->my);
  1546.         }
  1547.     }
  1548. }
  1549.  
  1550. /* unwatched hiders may hide again; if so, a 1 is returned.  */
  1551. STATIC_OVL boolean
  1552. restrap(mtmp)
  1553. register struct monst *mtmp;
  1554. {
  1555.     if(mtmp->cham || mtmp->mcan || mtmp->m_ap_type ||
  1556.        cansee(mtmp->mx, mtmp->my) || rn2(3) || (mtmp == u.ustuck))
  1557.         return(FALSE);
  1558.  
  1559.     if(mtmp->data->mlet == S_MIMIC) {
  1560.         set_mimic_sym(mtmp);
  1561.         return(TRUE);
  1562.     } else
  1563.         if(levl[mtmp->mx][mtmp->my].typ == ROOM)  {
  1564.         mtmp->mundetected = 1;
  1565.         return(TRUE);
  1566.         }
  1567.  
  1568.     return(FALSE);
  1569. }
  1570.  
  1571. /* make a chameleon look like a new monster; returns 1 if it actually changed */
  1572. int
  1573. newcham(mtmp, mdat)
  1574. register struct monst *mtmp;
  1575. register struct permonst *mdat;
  1576. {
  1577.     register int mhp, hpn, hpd;
  1578.     int tryct;
  1579.     struct permonst *olddata = mtmp->data;
  1580.  
  1581.     /* mdat = 0 -> caller wants a random monster shape */
  1582.     tryct = 0;
  1583.     if(mdat == 0) {
  1584.         while (++tryct < 100) {
  1585.             mdat = &mons[rn2(NUMMONS)];
  1586.             /* polyok rules out all M2_PNAME and M2_WERE's */
  1587.             if (!is_human(mdat) && polyok(mdat)
  1588.                     && !(mdat->geno & G_GENOD))
  1589.                 break;
  1590.         }
  1591.         if (tryct >= 100) return(0); /* Should never happen */
  1592.     }
  1593.  
  1594.     if(is_male(mdat)) {
  1595.         if(mtmp->female) mtmp->female = FALSE;
  1596.     } else if (is_female(mdat)) {
  1597.         if(!mtmp->female) mtmp->female = TRUE;
  1598.     } else if (!is_neuter(mdat)) {
  1599.         if(!rn2(10)) mtmp->female = !mtmp->female;
  1600.     }
  1601.  
  1602.     if (In_endgame(&u.uz) && is_mplayer(olddata)) {
  1603.         /* mplayers start out as "Foo the Bar", but some of the
  1604.          * titles are inappropriate when polymorphed, particularly
  1605.          * into the opposite sex.  players don't use ranks when
  1606.          * polymorphed, so dropping the rank for mplayers seems
  1607.          * reasonable.
  1608.          */
  1609.         char *p = index(NAME(mtmp), ' ');
  1610.         if (p) {
  1611.             *p = '\0';
  1612.             mtmp->mnamelth = p - NAME(mtmp) + 1;
  1613.         }
  1614.     }
  1615.  
  1616.     if(mdat == mtmp->data) return(0);    /* still the same monster */
  1617.  
  1618.     if(mtmp->wormno) {            /* throw tail away */
  1619.         wormgone(mtmp);
  1620.         place_monster(mtmp, mtmp->mx, mtmp->my);
  1621.     }
  1622.  
  1623.     hpn = mtmp->mhp;
  1624.     hpd = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
  1625.     if(!hpd) hpd = 4;
  1626.  
  1627.     mtmp->m_lev = adj_lev(mdat);        /* new monster level */
  1628.  
  1629.     mhp = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
  1630.     if(!mhp) mhp = 4;
  1631.  
  1632.     /* new hp: same fraction of max as before */
  1633. #ifndef LINT
  1634.     mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd);
  1635. #endif
  1636.     if(mtmp->mhp < 0) mtmp->mhp = hpn;    /* overflow */
  1637. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a
  1638.    0HD creature will require this statement */
  1639.     if (!mtmp->mhp) mtmp->mhp = 1;
  1640.  
  1641. /* and the same for maximum hit points */
  1642.     hpn = mtmp->mhpmax;
  1643. #ifndef LINT
  1644.     mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd);
  1645. #endif
  1646.     if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn;    /* overflow */
  1647.     if (!mtmp->mhpmax) mtmp->mhpmax = 1;
  1648.  
  1649.     mtmp->data = mdat;
  1650.     mtmp->minvis = !!(mdat->mlet == S_STALKER);
  1651.     if (!hides_under(mdat) || !OBJ_AT(mtmp->mx, mtmp->my))
  1652.         mtmp->mundetected = 0;
  1653.     if (u.ustuck == mtmp) {
  1654.         if(u.uswallow) {
  1655.             if(!attacktype(mdat,AT_ENGL)) {
  1656.                 /* Does mdat care? */
  1657.                 if (!noncorporeal(mdat) && !amorphous(mdat) &&
  1658.                     !is_whirly(mdat) &&
  1659.                     (mdat != &mons[PM_YELLOW_LIGHT])) {
  1660.                     You("break out of %s%s!", mon_nam(mtmp),
  1661.                         (is_animal(mdat)?
  1662.                         "'s stomach" : ""));
  1663.                     mtmp->mhp = 1;  /* almost dead */
  1664.                 }
  1665.                 expels(mtmp, olddata, FALSE);
  1666.             }
  1667.         } else {
  1668.             if(!sticks(mdat)
  1669. #ifdef POLYSELF
  1670.                 && !sticks(uasmon)
  1671. #endif
  1672.                 )
  1673.                 unstuck(mtmp);
  1674.         }
  1675.     }
  1676.  
  1677.     if ( (mdat == &mons[PM_LONG_WORM]) && (mtmp->wormno = get_wormno()) ) {
  1678.         /* we can now create worms with tails - 11/91 */
  1679.         initworm(mtmp, rn2(5));
  1680.         if (count_wsegs(mtmp))
  1681.         place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my);
  1682.     }
  1683.  
  1684.     newsym(mtmp->mx,mtmp->my);
  1685. #ifdef MUSE
  1686.     mon_break_armor(mtmp);
  1687.     /* Unfortunately, by now we forgot who did the polymorph, so we don't
  1688.      * have any way to give the player credit if this was a polymorph wand.
  1689.      */
  1690.     mselftouch(mtmp, "No longer petrify-resistant, ", FALSE);
  1691.     possibly_unwield(mtmp);
  1692. #endif
  1693.     return(1);
  1694. }
  1695.  
  1696. #endif /* OVL2 */
  1697. #ifdef OVLB
  1698.  
  1699. void
  1700. golemeffects(mon, damtype, dam)
  1701. register struct monst *mon;
  1702. int damtype, dam;
  1703. {
  1704.     int heal=0, slow=0;
  1705.  
  1706.     if (mon->data != &mons[PM_FLESH_GOLEM]
  1707.                     && mon->data != &mons[PM_IRON_GOLEM])
  1708.         return;
  1709.  
  1710.     if (mon->data == &mons[PM_FLESH_GOLEM]) {
  1711.         if (damtype == AD_ELEC) heal = dam / 6;
  1712.         else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1;
  1713.     } else {
  1714.         if (damtype == AD_ELEC) slow = 1;
  1715.         else if (damtype == AD_FIRE) heal = dam;
  1716.     }
  1717.     if (slow) {
  1718.         if (mon->mspeed != MSLOW) {
  1719.             if (mon->mspeed == MFAST) mon->mspeed = 0;
  1720.             else mon->mspeed = MSLOW;
  1721.             if (cansee(mon->mx, mon->my))
  1722.                 pline("%s seems to be moving slower.",
  1723.                     Monnam(mon));
  1724.         }
  1725.     }
  1726.     if (heal) {
  1727.         if (mon->mhp < mon->mhpmax) {
  1728.             mon->mhp += dam;
  1729.             if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax;
  1730.             if (cansee(mon->mx, mon->my))
  1731.                 pline("%s seems healthier.", Monnam(mon));
  1732.         }
  1733.     }
  1734. }
  1735.  
  1736. boolean
  1737. angry_guards(silent)
  1738. register boolean silent;
  1739. {
  1740.     register struct monst *mtmp;
  1741.     register int ct = 0, nct = 0, sct = 0, slct = 0;
  1742.  
  1743.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1744.         if((mtmp->data == &mons[PM_WATCHMAN] ||
  1745.                    mtmp->data == &mons[PM_WATCH_CAPTAIN])
  1746.                     && mtmp->mpeaceful) {
  1747.             ct++;
  1748.             if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
  1749.                 if (distu(mtmp->mx, mtmp->my) == 2) nct++;
  1750.                 else sct++;
  1751.             }
  1752.             if(mtmp->msleep || mtmp->mfrozen) {
  1753.                 slct++;
  1754.                 mtmp->msleep = mtmp->mfrozen = 0;
  1755.             }
  1756.             mtmp->mpeaceful = 0;
  1757.         }
  1758.     }
  1759.     if(ct) {
  1760.         if(!silent) { /* do we want pline msgs? */
  1761.         if(slct) pline("The guard%s wake%s up!",
  1762.                  slct > 1 ? "s" : "", slct == 1 ? "s" : "");
  1763.         if(nct || sct) {
  1764.             if(nct) pline("The guard%s get%s angry!",
  1765.                 nct == 1 ? "" : "s", nct == 1 ? "s" : "");
  1766.             else if(!Blind)
  1767.                 You("see %sangry guard%s approaching!",
  1768.                   sct == 1 ? "an " : "", sct > 1 ? "s" : "");
  1769.         } else if(flags.soundok)
  1770.             You("hear the shrill sound of a guard's whistle.");
  1771.         }
  1772.         return(TRUE);
  1773.     }
  1774.     return(FALSE);
  1775. }
  1776.  
  1777. void
  1778. pacify_guards()
  1779. {
  1780.     register struct monst *mtmp;
  1781.  
  1782.     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1783.         if (mtmp->data == &mons[PM_WATCHMAN] ||
  1784.         mtmp->data == &mons[PM_WATCH_CAPTAIN])
  1785.         mtmp->mpeaceful = 1;
  1786.     }
  1787. }
  1788. #endif /* OVLB */
  1789.  
  1790. /*mon.c*/
  1791.